<template>
  <editor
    v-model="myValue"
    :init="init"
    :disabled="disabled"
    :id="tinymceId"
  ></editor>
</template>

<script setup>
import request from "@/utils/request";

//JS部分
//在js中引入所需的主题和组件
import tinymce from "tinymce/tinymce";
import "tinymce/skins/content/default/content.css";
import Editor from "@tinymce/tinymce-vue";
import "tinymce/themes/silver";
import "tinymce/themes/silver/theme";
import "tinymce/icons/default"; //引入编辑器图标icon，不引入则不显示对应图标
import "tinymce/models/dom"; // 这里是个坑 一定要引入

//在TinyMce.vue中接着引入相关插件
import "tinymce/icons/default/icons";
import "tinymce/plugins/image"; // 插入上传图片插件
import "tinymce/plugins/media"; // 插入视频插件
import "tinymce/plugins/table"; // 插入表格插件
import "tinymce/plugins/lists"; // 列表插件
import "tinymce/plugins/wordcount"; // 字数统计插件
import "tinymce/plugins/code"; // 源码
import "tinymce/plugins/fullscreen"; //全屏
import "tinymce/plugins/help";
import "tinymce/plugins/link";
import "./formatpainter.min"; // 格式刷
import "./indent2em.min"; // 首行缩进
import { ElMessage } from "element-plus";

//接下来定义编辑器所需要的插件数据
import { reactive, ref, onMounted, defineEmits, watch } from "vue";

const emits = defineEmits(["change", "update:modelValue"]);
const uploadUrl = ref(
  import.meta.env.VITE_APP_BASE_API + "/system/file/upload"
);

const props = defineProps({
  modelValue: {
    type: String,
    default: () => {
      return "";
    },
  },
  // 自定义富文本内容样式
  customStyle: {
    type: String,
    default: "", // 自定义样式一定要标准写法带 `;` 如： `font-family: PingFangSC-Regular;font-size: 18px;`
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  plugins: {
    type: [String, Array],
    default:
      "image media fullscreen table lists code help link formatpainter indent2em",
  }, //必填
  toolbar: {
    type: [String, Array],
    default:
      "formatpainter codesample bold italic underline alignleft aligncenter alignright alignjustify | undo redo | formatselect | fontselect | fontsizeselect | forecolor backcolor | bullist numlist outdent indent indent2em | lists link table code | removeformat",
  }, //必填
});
import "tinymce/plugins/media";
//用于接收外部传递进来的富文本
const myValue = ref(decodeURIComponent(props.modelValue));
const tinymceId = ref(
  "vue-tinymce-" + +new Date() + ((Math.random() * 1000).toFixed(0) + "")
);
//定义一个对象 init初始化
const init = reactive({
  selector: "#" + tinymceId.value, //富文本编辑器的id,
  language_url: "https://dcb-frontend.gogpay.cn/editor-tinymce/zh-Hans.js", // 语言包的路径
  language: "zh-Hans", //语言
  skin_url: "https://dcb-frontend.gogpay.cn/editor-tinymce/skins/ui/oxide", // skin路径
  height: 400, //编辑器高度
  branding: false, //是否禁用“Powered by TinyMCE”
  menubar: true, //顶部菜单栏显示
  image_dimensions: false, //去除宽高属性
  plugins: props.plugins, //这里的数据是在props里面就定义好了的
  toolbar: props.toolbar, //这里的数据是在props里面就定义好了的
  font_formats:
    "Arial=arial,helvetica,sans-serif; 宋体=SimSun; 微软雅黑=Microsoft Yahei; Impact=impact,chicago;", //字体
  fontsize_formats: "11px 12px 14px 16px 18px 24px 36px 48px 64px 72px", //文字大小
  // paste_convert_word_fake_lists: false, // 插入word文档需要该属性
  paste_webkit_styles: "all",
  paste_merge_formats: true,
  nonbreaking_force_tab: false,
  paste_auto_cleanup_on_paste: false,
  file_picker_types: "file",
  content_css:
    "https://dcb-frontend.gogpay.cn/editor-tinymce/skins/content/default/content.css", //以css文件方式自定义可编辑区域的css样式
  //图片上传
  images_upload_handler: (blobInfo, progress) =>
    new Promise((resolve, reject) => {
      if (blobInfo.blob().size / 1024 / 1024 > 5) {
        reject({ message: "上传失败，图片大小请控制在 5M 以内", remove: true });
        return;
      } else {
        let params = new FormData();
        params.append("file", blobInfo.blob());
        request({
          url: uploadUrl.value,
          method: "post",
          data: params,
          timeout: 1000 * 60 * 10,
        })
          .then((res) => {
            if (res.code == 200) {
              resolve(res.data.url); //上传成功，在成功函数里填入图片路径
            } else {
              reject("上传失败" + res.msg);
              return;
            }
          })
          .catch((err) => {
            reject("上传出错");
            return;
          });
      }
    }),

  // 文件上传
  file_picker_callback: (callback, value, meta) => {
    let filetype =
      ".pdf, .txt, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .mp4, .avi, .jpg, .jpeg, .png, .gif"; //限制文件的上传类型
    let inputElem = document.createElement("input"); //创建文件选择
    inputElem.setAttribute("type", "file");
    inputElem.setAttribute("accept", filetype);
    inputElem.click();
    inputElem.onchange = () => {
      let file = inputElem.files[0]; //获取文件信息
      let params = new FormData();
      params.append("file", file);
      if (file.type.slice(0, 5) == "image" && file.size / 1024 / 1024 > 5) {
        ElMessage.error("上传失败，图片大小请控制在5M以内");
      } else if (
        file.type.slice(0, 5) == "video" &&
        file.size / 1024 / 1024 > 50
      ) {
        ElMessage.error("上传失败，视频大小请控制在 50M 以内");
      } else if (file.size / 1024 / 1024 > 10) {
        ElMessage.error("上传失败，文件大小请控制在 10M 以内");
      } else {
        request({
          url: uploadUrl.value,
          method: "post",
          data: params,
          timeout: 1000 * 60 * 10,
        })
          .then((res) => {
            if (res.code == 200) {
              callback(res.url, {
                text: res.data.name,
                title: res.data.name,
              });
            } else {
              ElMessage.error("上传失败" + res.msg);
            }
          })
          .catch((err) => {
            ElMessage.error("上传出错");
          });
      }
    };
  },
});
// 自定义富文本样式，一般用于展示时有特殊统一样式要求
const customStyleFn = (html) => {
  if (!props.customStyle) {
    return html;
  }
  const regex = /style="([^"]*)"/g;
  return html.replace(regex, `style="${props.customStyle} $1"`); // 在style首行插入
  // return html.replace(regex, `style="$1 ${props.customStyle}"`); // 在style尾行插入
};

//监听外部传递进来的的数据变化
watch(
  () => props.modelValue,
  () => {
    myValue.value = decodeURIComponent(props.modelValue);
    emits("update:modelValue", encodeURIComponent(myValue.value));
    emits("change", encodeURIComponent(myValue.value));
  }
);
//监听富文本中的数据变化
watch(
  () => myValue.value,
  () => {
    emits("update:modelValue", encodeURIComponent(myValue.value));
    emits("change", encodeURIComponent(myValue.value));
  }
);
//在onMounted中初始化编辑器
onMounted(() => {
  tinymce.init({});
});
</script>
